using System;
using System.Collections;
using System.Security.Principal;
using System.Web;
using System.Reflection;
using System.Data;

using Castle.Facilities.NHibernateIntegration;
using Castle.Services.Transaction;
using NHibernate;
using NetBpm.Util.Client;
using NetBpm.Workflow.Organisation.EComp;
using NetBpm.Workflow.Organisation;
using NetBpm.Workflow.Delegation;
using NetBpm.Workflow.Definition;
using NetBpm.Workflow.Definition.EComp;
using NetBpm.Workflow.Execution;
using NetBpm.Workflow.Execution.EComp;
using NetBpm.Workflow.Definition.Attr;
using NetBpm.Workflow.Log.EComp;

using BEGDC.Utility.ExceptionManagement;
using BEGDC.CC.BL.Workflow;
using BEGDC.CC.BL.Common;
using BEGDC.Utility.Castle;
using BEGDC.CC.Entity;


namespace BEGDC.CC.BL.CCFlow.EV
{
	public class EVFlow : FlowBase
	{
        
		protected override string ProjectType
		{
			get
			{
				return WorkflowTypes.EV;
			}
		}


		public long StartAPFlow()
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				long processDefinitionID = BEGDC.CC.BL.Workflow.Configuration.GetProcessDefinitionID(WorkflowTypes.AP);
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;
				IProcessInstance processInstance = executionComponent.StartProcessInstance(processDefinitionID);
				return processInstance.RootFlow.Id;
			}
			catch(Exception ex)
			{
				throw new Exception("Start Process error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}

		public void APPerform( long flowID, string nextTransition)
		{

			IDictionary attributes = new Hashtable();				
			attributes.Add(NEXT_TRANSITION, nextTransition);

			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				executionComponent.PerformActivity( flowID, attributes );
			}
			catch
			{
			}
		}

		public void SaveFlowInstance(ISession session, FlowInstance flowInstance )
		{
			if( flowInstance == null )
				throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.NoInstance_Exception, "No instance to Save");

			try
			{
				if( session.IsOpen )
				{
					session.SaveOrUpdate( flowInstance );
				}
				else
				{
					throw new GDCException( BEGDC.CC.BL.Common.ErrorCode.DB_Exception, "Session is closed");
				}
			}
			catch( Exception )
			{
				throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.DB_Exception, "Failed to save flow infomation");
			}
		}

		public void Perform(ISession session, Application app, string nextTransition)
		{
			long flowId = 0;
			if( app != null )
			{
				BEGDC.CC.BL.Common.Query.IQuery queryService= BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
				flowId = queryService.QueryFlowInstance(app.Id).FlowID;
			}
			else
				throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.Null_Exception, "Application object is null");
			base.Perform(session, flowId, nextTransition, string.Empty);
		}

		public void Perform(ISession session, Application app, string nextTransition, string comment)
		{
			long flowId = 0;
			if( app != null )
			{
				BEGDC.CC.BL.Common.Query.IQuery queryService= BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
				flowId = queryService.QueryFlowInstance(app.Id).FlowID;
			}
			else
				throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.Null_Exception, "Application object is null");
			base.Perform(session, flowId, nextTransition, comment);
		}

		public void Drawback( ISession session, Application app )
		{
			long flowId = 0;
			if( app != null )
			{
				BEGDC.CC.BL.Common.Query.IQuery queryService= BEGDC.Utility.Castle.AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
				flowId = queryService.QueryFlowInstance(app.Id).FlowID;
			}
			else
				throw new GDCException(BEGDC.CC.BL.Common.ErrorCode.Null_Exception, "Application object is null");
			
			base.Drawback( session, flowId, string.Empty);
		}
		

	}
}